--[[ 编码: WMS-16-20 名称: 盘点计划-盘点计划启动 作者:HAN 日期:2025-1-29 级别:固定 (说明本段代码在项目中不太会变化) 函数: AllocPlanContainer 功能: 根据盘点计划类型生成计划盘点容器 更改记录: V2.0 HAN 20250213 -- 新增容器盘点类型 --]] wms_base = require( "wms_base" ) -- 创建 计划盘点容器 -- cp_no 盘点计划号 cntr_code 容器号 item_code 货品编码 local function create_cp_count_container( strLuaDEID, cp_no, cntr_code, item_code ) local nRet, strRetInfo -- step1 盘点一下当前【计划盘点容器】里是否已经存在这个容器 local strCondition = "S_CP_NO = '" .. cp_no .. "' AND S_CNTR_CODE = '"..cntr_code.."'" local cp_count_container if ( item_code == nil ) then item_code = '' end nRet, cp_count_container = m3.GetDataObjByCondition( strLuaDEID,"CP_Count_Container", strCondition ) if (nRet == 1) then -- 不存在要创建 【CP_Count_Container】 cp_count_container = m3.AllocObject(strLuaDEID,"CP_Count_Container") cp_count_container.cp_no = cp_no cp_count_container.cntr_code = cntr_code if (item_code ~='') then cp_count_container.good_codes = '["'..item_code..'"]' end nRet, cp_count_container = m3.CreateDataObj( strLuaDEID, cp_count_container ) if (nRet ~= 0) then return 1, cp_count_container end return 0 end if ( nRet ~= 0 ) then return 1, cp_count_container end if ( item_code == '') then return 0 end -- 已经存在 更新 容器里要 盘点的货物编码 str_good_codes = cp_count_container.good_codes local good_codes = {} local nIndex = 1 if (str_good_codes ~= '') then good_codes = json.decode(str_good_codes) nIndex = #good_codes + 1 end -- 判断 item_code 是否已经存在, 如果已经存就不需要加 if ( lua.IsInTable( item_code, good_codes ) ) then return 0 end good_codes[nIndex] = item_code local id = lua.trim_guid_str( cp_count_container.id ) strCondition = "S_ID = '"..id.."'" local strSetAttr = "S_GOOD_CODES = '"..lua.table2str(good_codes).."'" nRet, strRetInfo = mobox.updateDataAttrByCondition( strLuaDEID, "CP_Count_Container", strCondition, strSetAttr ) if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), "updateDataAttrByCondition失败"..strRetInfo ) end return 0 end -- 根据 CP_Good_list 中的记录查询出这些货品所在的 容器,生成计划盘点容器 -- count_plan 盘点计划 -- data_set 需要盘点的货物 CP_Good_list local function alloc_cntr_by_cp_good_list( strLuaDEID, count_plan, data_set ) local n, good, nRet, strRetInfo, i local str_loc_condition -- 货位条件 local str_good_condition -- 货物条件 local str_condition str_loc_condition = "S_WH_CODE ='"..count_plan.wh_code.."' " -- MDF BY HAN 2025-2-28 考虑到根据货品盘点时,如果容器在移动中,这个时候就获取不全容器,因此把库区取消 N_PURPOSE 也不考虑 -- N_PURPOSE = 1 表示货位是存储位 --[[ str_loc_condition = "S_WH_CODE ='"..count_plan.wh_code.."' AND N_PURPOSE = 1" if ( count_plan.area_code ~= '' and count_plan.area_code ~= nil ) then str_loc_condition = str_loc_condition.." AND S_AREA_CODE ='"..count_plan.area_code.."'" end ]] local success local queryInfo local queryID, nPageCount, nPage, dataSet, cntr_code, i local strOrder = "S_CNTR_CODE" for n = 1, #data_set do nRet, good = m3.ObjAttrStrToLuaObj( "CP_Good_List", lua.table2str(data_set[n].attrs) ) if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), "m3.ObjAttrStrToLuaObj 失败! "..good ) end str_good_condition = "S_ITEM_CODE = '"..good.item_code.."' ".. "AND S_CNTR_CODE in ".. "(select S_CNTR_CODE from TN_Loc_Container with (NOLOCK) where S_LOC_CODE in (select S_CODE from TN_Location with (NOLOCK) where "..str_loc_condition.."))" -- 查询有该货品的容器编号 -- 获取货品所在容器(考虑到有比较极端情况容器数量大于1000因此采用 queryDataObjAttr2 ) nRet, strRetInfo = mobox.queryDataObjAttr2( strLuaDEID, "CG_Detail", str_good_condition, strOrder, 100, "S_CNTR_CODE" ) if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), "queryDataObjAttr2: "..strRetInfo) end if ( strRetInfo == '' ) then goto continue end success, queryInfo = pcall( json.decode, strRetInfo ) if ( success == false ) then lua.Error( strLuaDEID, debug.getinfo(1), "queryDataObjAttr2 返回结果啊非法的JSON格式!" ) end queryID = queryInfo.queryID nPageCount = queryInfo.pageCount nPage = 1 dataSet = queryInfo.dataSet -- 查询出来的数据集 while (nPage <= nPageCount) do for i = 1, #dataSet do cntr_code = dataSet[i].attrs[1].value nRet, strRetInfo = create_cp_count_container( strLuaDEID, count_plan.cp_no, cntr_code, good.item_code ) if ( nRet ~= 0 ) then return 1, "create_cp_count_container失败! ".. strRetInfo end end nPage = nPage + 1 if ( nPage <= nPageCount ) then -- 取下一页 nRet, strRetInfo = mobox.queryDataObjAttr2( queryID, nPage) if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), "queryDataObjAttr2失败! nPage="..nPage.." "..strRetInfo ) end queryInfo = json.decode(strRetInfo) dataSet = queryInfo.dataSet end end ::continue:: end return 0 end -- 根据 CP_Location_list 中的记录查询出这些货位中存在的容器进行盘点 -- count_plan 盘点计划 -- data_set 需要盘点的货物 CP_Location_list local function alloc_cntr_by_cp_location_list( strLuaDEID, count_plan, data_set ) local n, nRet, strRetInfo, strCondition local location local strOrder = "N_BIND_ORDER" local object_attr for n = 1, #data_set do nRet, location = m3.ObjAttrStrToLuaObj( "CP_Location_list", lua.table2str(data_set[n].attrs) ) if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), "m3.ObjAttrStrToLuaObj 失败! "..location ) end strCondition = "S_LOC_CODE ='"..location.loc_code.."'" -- 获取货位绑定的容器号 local data_objs, i nRet, data_objs = m3.QueryDataObject(strLuaDEID, "Loc_Container", strCondition, strOrder ) if (nRet ~= 0) then return 1, data_objs end if ( data_objs ~= '') then for i = 1, #data_objs do object_attr = m3.KeyValueAttrsToObjAttr(data_objs[i].attrs) nRet, strRetInfo = create_cp_count_container( strLuaDEID, count_plan.cp_no, object_attr.S_CNTR_CODE ) if ( nRet ~= 0 ) then return 1, strRetInfo end end end end return 0 end function AllocPlanContainer ( strLuaDEID ) local nRet, strRetInfo local count_plan nRet, count_plan = m3.GetSysCurEditDataObj( strLuaDEID, "Count_Plan" ) if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), "获取当前编辑属性失败! "..count_plan ) end local strCurEditClsID, strCurEditObjID nRet, strCurEditClsID, strCurEditObjID = mobox.getCurEditDataObjID( strLuaDEID ) if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), "getCurEditDataObjID失败! " ) end -- 如果已经启动过就不要再做后面的程序 if ( count_plan.b_state > 1 ) then lua.Warning( strLuaDEID, debug.getinfo(1), "盘点计划编号 = '"..count_plan.cp_no.."' 已经启动过不需要再次启动!" ) return end local strCondition, strClsID local strOrder strCondition = "S_CP_NO = '"..count_plan.cp_no.."'" if ( count_plan.type == wms_base.Get_nConst(strLuaDEID,"盘点类型-货品盘点") ) then -- 获取 【CP_Good_List】 strClsID = "CP_Good_List" strOrder = "S_ITEM_CODE" elseif ( count_plan.type == wms_base.Get_nConst(strLuaDEID,"盘点类型-货位盘点") ) then strClsID = "CP_Location_List" strOrder = "S_LOC_CODE" -- V2.0 else strClsID = "" end -- 多页查询 if ( strClsID ~= '') then nRet, strRetInfo = mobox.queryDataObjAttr2( strLuaDEID, strClsID, strCondition, strOrder, 100 ) if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), "queryDataObjAttr2: "..strRetInfo) end if ( strRetInfo == '' ) then return end local success local queryInfo success, queryInfo = pcall( json.decode, strRetInfo ) if ( success == false ) then lua.Error( strLuaDEID, debug.getinfo(1), "queryDataObjAttr2 返回结果啊非法的JSON格式!" ) end local queryID = queryInfo.queryID local nPageCount = queryInfo.pageCount local nPage = 1 local dataSet = queryInfo.dataSet -- 查询出来的数据集 while (nPage <= nPageCount) do if ( count_plan.type == wms_base.Get_nConst(strLuaDEID,"盘点类型-货品盘点") ) then -- 通过计划盘点货品查找 计划盘点的容器 nRet, strRetInfo = alloc_cntr_by_cp_good_list( strLuaDEID, count_plan, dataSet ) if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), "alloc_cntr_by_cp_good_list: "..strRetInfo) end else nRet, strRetInfo = alloc_cntr_by_cp_location_list( strLuaDEID, count_plan, dataSet ) if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), "alloc_cntr_by_cp_location_list: "..strRetInfo) end end nPage = nPage + 1 if ( nPage <= nPageCount ) then -- 取下一页 nRet, strRetInfo = mobox.queryDataObjAttr2( queryID, nPage) if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), "queryDataObjAttr2失败! nPage="..nPage.." "..strRetInfo ) end queryInfo = json.decode(strRetInfo) dataSet = queryInfo.dataSet end end end -- 获取 计划盘点容器【CP_Count_Container】数量 strCondition = "S_CP_NO = '"..count_plan.cp_no.."'" nRet, strRetInfo = mobox.getDataObjCount( strLuaDEID, "CP_Count_Container", strCondition ) if ( nRet ~= 0 ) then return nRet, strRetInfo end local nCount = lua.StrToNumber( strRetInfo ) local strSetAttr if ( nCount == 0 ) then -- 如果计划盘点容器为 0 表示没有找到盘点的容器,设置状态为错误 strSetAttr = "N_B_STATE = 4, N_PLAN_TOTAL = 0, S_ERR = '没有找到匹配的容器!'" else strSetAttr = "N_B_STATE = 2, N_PLAN_TOTAL = "..nCount end nRet, strRetInfo = mobox.updateDataAttrByCondition( strLuaDEID, "Count_Plan", strCondition, strSetAttr ) if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), "updateDataAttrByCondition失败"..strRetInfo ) end if ( nCount == 0 ) then return end -- 设置计划盘点容器表中的货位信息 local add_wfp_paramter = {} add_wfp_paramter.wfp_type = 1 -- 触发数据对象事件(指定数据对象标识) add_wfp_paramter.cls = strCurEditClsID add_wfp_paramter.obj_id = strCurEditObjID add_wfp_paramter.trigger_event = "刷新计划盘点容器货位信息" nRet, strRetInfo = m3.AddSysWFP( strLuaDEID, add_wfp_paramter ) if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), strRetInfo ) end end